<template>
  <div class="file-list">
    <div class="file-list-header">
      <div>
        <h3>{{ title }}</h3>
        <p>最近访问 · {{ files.length }} 个文件</p>
      </div>
      <div class="btn-group">
        <el-upload class="upload-demo" action="/api/knowledge/upload" :file-list="fileList"
          :data="{ knowledgeCode: knowledgeCode }" :before-upload="beforeUpload" :on-success="handleSuccess"
          :on-error="handleError" :show-file-list="false" :limit="1" :on-exceed="handleExceed" multiple auto-upload
          list-type="text">
          <el-button type="primary" size="small" style="background-color: #165dff;">📤 选择并上传文件</el-button>
        </el-upload>
      </div>
    </div>

    <el-table :data="files" border stripe>
      <el-table-column label="文件名" min-width="250">
        <template slot-scope="scope">
          <i :class="getFileIcon(scope.row.fileType)" style="margin-right: 6px;"></i>
          {{ scope.row.fileName }}
        </template>
      </el-table-column>
      <el-table-column label="文件类型" width="100" prop="fileType" />
      <el-table-column label="上传时间" width="180" prop="createTime" />
      <el-table-column label="修改时间" width="180" prop="updateTime" />
      <el-table-column label="大小" width="100" prop="fileSizeStr" />

      <el-table-column label="状态" width="100">
        <template slot-scope="scope">
          <el-tag :type="scope.row.statusType === '已处理' ? 'success' : 'warning'" disable-transitions>
            {{ scope.row.statusType }}
          </el-tag>
        </template>
      </el-table-column>

      <el-table-column label="操作" width="100">
        <template slot-scope="scope">
          <el-button type="text" icon="el-icon-view" @click="$file.handleKnowledgeFileNameClick(scope.row)"></el-button>
          <el-button type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"></el-button>
        </template>
      </el-table-column>
    </el-table>

    <div class="view-more">
      <el-link type="primary" @click="handleViewMore">查看全部文件</el-link>
    </div>
  </div>
</template>

<script>
export default {
  name: 'FileList',
  props: {
    title: {
      type: String,
      default: '业务文档库'
    },
    files: {
      type: Array,
      required: true
    },
    knowledgeCode: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      fileList: [],
      allowedTypes: [
        'application/pdf',
        'application/msword',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        'application/vnd.ms-excel',
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'text/plain',
      ],
      loadingInstance: null,
    }
  },
  methods: {
    beforeUpload(file) {
      const isAllowed = this.allowedTypes.includes(file.type);
      const isLt5M = file.size / 1024 / 1024 < 5;

      if (!isAllowed) {
        this.$message.error('❌ 仅支持 PDF、Word、Excel、TXT 文档，禁止上传图片、音视频！');
        return false;
      }
      if (!isLt5M) {
        this.$message.error('❌ 文件大小不能超过 5MB！');
        return false;
      }

      // ✅ 开启全局 loading
      this.loadingInstance = this.$loading({
        lock: true,
        text: '文件已上传，正在进行智能解析，请耐心等待约 5~10 秒…',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.3)',
      });
      return true;
    },
    handleSuccess(response, file) {
      this.closeLoading();
      this.$emit('dataLoadding');
      this.$message.success(`✅ "${file.name}" 上传成功`);
      this.fileList = []
    },
    handleError(err, file) {
      this.closeLoading();
      this.$message.error(`❌ "${file.name}" 上传失败`);
      this.fileList = []
    },
    handleExceed(files, fileList) {
      this.$message.warning('⚠️ 最多只能上传 1 个文件');
    },
    // 关闭 loading（确保一定会被调用）
    closeLoading() {
      if (this.loadingInstance) {
        this.loadingInstance.close();
        this.loadingInstance = null;
      }
    },
    /**
     * 
     * @param fileType 获取文件 icon 图标
     */
    getFileIcon(fileType) {
      switch (fileType) {
        case 'pdf':
          return 'el-icon-document';
        case 'docx':
          return 'el-icon-document';
        case 'xlsx':
          return 'el-icon-s-data';
        case 'pptx':
          return 'el-icon-s-marketing';
        default:
          return 'el-icon-document';
      }
    },
    /** 文件预览 */
    handlePreview(file) {
      this.$message(`预览文件：${file.fileName}`)

      const fileSuffix = (file.extendName || '').toLowerCase()

      // 拦截图片、音频、视频类型，不处理
      const IMAGE_TYPES = ['png', 'jpg', 'jpeg', 'gif', 'svg']
      const VIDEO_TYPES = ['mp4']
      const AUDIO_TYPES = ['mp3', 'flac']

      if (
        IMAGE_TYPES.includes(fileSuffix) ||
        VIDEO_TYPES.includes(fileSuffix) ||
        AUDIO_TYPES.includes(fileSuffix)
      ) {
        this.$message.warning('该文件类型不支持预览')
        return
      }

      // Office 文件在线预览
      if ([...officeFileType].includes(fileSuffix)) {
        this.getFileOnlineViewPathByOffice(file)
        return
      }

      // PDF 文件新标签页打开
      if (fileSuffix === 'pdf') {
        window.open(this.getViewFilePath(file), '_blank')
        return
      }

      // 统一 yaml => yml
      let codeSuffix = fileSuffix === 'yaml' ? 'yml' : fileSuffix

      // Markdown 文档
      if (markdownFileType.includes(codeSuffix)) {
        Vue.prototype.$openBox.markdownPreview({
          fileInfo: file,
          editable: false
        })
        return
      }

      // 文本/代码类文件 或 无扩展名文件
      if (
        fileSuffixCodeModeMap.has(codeSuffix) ||
        (file.isDir === 0 && !file.extendName)
      ) {
        Vue.prototype.$openBox.codePreview({ fileInfo: file, isEdit: false })
        return
      }

      // 其他不支持预览
      this.$message.warning('暂不支持该类型文件预览')
    },
    /**
     * 
     * @param file 文件删除操作
     */
    handleDelete(file) {
      this.$confirm(`确定删除 ${file.fileName} 吗？`, '删除确认')
        .then(() => {
          this.$emit('fileDelete', file);
        })
        .catch(() => { });
    },
    handleViewMore() {
      this.$message('加载更多文件...');
    }
  }
}
</script>

<style scoped>
.file-list {
  margin-top: 32px;
  background: #fff;
  padding: 24px;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.file-list-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.file-list-header h3 {
  margin: 0;
}

.btn-group {
  display: flex;
  gap: 10px;
}

.view-more {
  margin-top: 12px;
  text-align: center;
}
</style>
